/**
 * @(#) CoordinateContextImpl.java
 */

package org.vsg.stock.core.indicator.coordinate;

import java.text.DecimalFormat;
import java.util.Calendar;

import org.springframework.util.Assert;
import org.vsg.stock.core.indicator.coordinate.origpoint.SimpleOriginalDataPoint;
import org.vsg.stock.core.utils.StockDateUtilExtension;

class CoordinateContextImpl implements CoordinateContext
{

	private OriginalDataPoint opoint;
	
	private UnitDefinition unitDefinition;
	
	private String stockCode;
	
	/**
	 * @param originPoint
	 */
	public void setOriginPoint(OriginalDataPoint originPoint) {
		opoint = originPoint;
	}
	
	/**
	 * @param unitDefinition
	 */
	public void setUnitDefinition(UnitDefinition unitDefinition ) {
		this.unitDefinition = unitDefinition;
	}
	
	/**
	 * @return 
	 */
	@Override
	public OriginalDataPoint getOriginPoint() {
		// TODO Auto-generated method stub
		return opoint;
	}

	/**
	 * @return 
	 */
	@Override
	public UnitDefinition getUnitDefinition() {
		// TODO Auto-generated method stub
		return this.unitDefinition;
	}

	/**
	 * @return 
	 */
	@Override
	public String getStockCode() {
		return stockCode;
	}
	
	public void setStockCode(String stockCode) {
		this.stockCode = stockCode;
	}

	private StockDateUtilExtension stkDateUtilExtension;

	public StockDateUtilExtension getStkDateUtilExtension() {
		return stkDateUtilExtension;
	}

	public void setStkDateUtilExtension(StockDateUtilExtension stkDateUtilExtension) {
		this.stkDateUtilExtension = stkDateUtilExtension;
	}
	
	
	public CoordinatePoint transformToCoordinatePoint(OriginalDataPoint relaPoint) {
		
		Assert.notNull(stkDateUtilExtension, "Stock Date til Extension not defined! ");

		OriginalDataPoint originPoint = this.getOriginPoint();
		
		UnitDefinition udef = this.getUnitDefinition();
	
		DecimalFormat df = new DecimalFormat("0.0");
		
		// ---- get the x & y value ,最低价离原点收盘价 ---
		double yDiff = relaPoint.getYvalue() - originPoint.getYvalue();		


		int cycleDays = stkDateUtilExtension.getDifferenceValue(this.getStockCode(),
				originPoint.getXvalue(), relaPoint.getXvalue());
		
		
		// ---- count the unit value ---
		double y = yDiff / udef.getYUnit();
		y = Double.parseDouble( df.format( y ) );
		
		double x = cycleDays / udef.getXUnit();
				
		// --- set the CoordinatePoint ----
		SimpleCoordinatePoint coordinatePoint = new SimpleCoordinatePoint();
		coordinatePoint.setXvalue( x );
		coordinatePoint.setYvalue( y );
		
		return coordinatePoint;		

	}

	@Override
	public OriginalDataPoint transformToOriginalDataPoint(
			CoordinatePoint relaPoint) {
		Assert.notNull(stkDateUtilExtension, "Stock Date til Extension not defined! ");

		OriginalDataPoint originPoint = this.getOriginPoint();
		
		UnitDefinition udef = this.getUnitDefinition();		
		
		double yDiff = relaPoint.getYvalue() * udef.getYUnit();
		
		double cycleDays = relaPoint.getXvalue() * udef.getXUnit();
		
		Calendar tmpCalendar = Calendar.getInstance();
		tmpCalendar.setTime( originPoint.getXvalue() );

		double absCycleDays = Math.abs(cycleDays);
		while (absCycleDays > 0 ) {
			
			if ( cycleDays > 0) {
				tmpCalendar.add(Calendar.DATE, 1);
			} 
			else if(cycleDays < 0) {
				tmpCalendar.add(Calendar.DATE, -1);				
			}
			boolean che = stkDateUtilExtension.isTradingDate(tmpCalendar);
			if ( che ) {
				absCycleDays = absCycleDays -1;
			}
		}

		SimpleOriginalDataPoint originalDataPoint = new SimpleOriginalDataPoint(yDiff , tmpCalendar.getTime());		
		
		return originalDataPoint;
	}

	
	
}
